﻿using MCUPackage;
using MCUPackage.Utils;
using SxPackages.STC32G.DesignEditor;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Text;

namespace SxPackages.STC32G.Models
{
	[Serializable]
	class SoftIICOptions : IICOptions
	{
		public override Boolean Enable
		{
			get => base.Enable;
			set
			{
				if (value != base.Enable)
				{
					if (value)
					{
						// 检查已经设置的引脚之间是否冲突
						if (TemplateHelper.PinsIsRepeat(mUsePins))
						{
							return;
						}
					}
					base.Enable = value;
				}
			}
		}

		public override Boolean Master => true;

		[Browsable(false)]
		public override Int32 Speed => 63;

		[Browsable(false)]
		public override IICPins Pins { get => base.Pins; set => base.Pins = value; }

		[Browsable(false)]
		public override Boolean EnableTI => false;
		[Browsable(false)]
		public override PriorityTypes Priority => PriorityTypes.最低级;

		[Browsable(false)]
		public override Int32 SADR => 0;

		[Browsable(false)]
		public override Boolean SL_MA => false;

		[Browsable(false)]
		public override Boolean WDTA => false;

		[Browsable(false)]
		public override Boolean EnableDMARcv => false;
		[Browsable(false)]
		public override Boolean EnableDMASnd => false;
		[Browsable(false)]
		public override Int32 RcvLength { get => base.RcvLength; set => base.RcvLength = value; }
		[Browsable(false)]
		public override Int32 SndLength { get => base.SndLength; set => base.SndLength = value; }
		[Browsable(false)]
		public override PriorityTypes DMAPriority { get => base.DMAPriority; set => base.DMAPriority = value; }
		[Browsable(false)]
		public override PriorityTypes BusPriority { get => base.BusPriority; set => base.BusPriority = value; }

		/// <summary>
		/// 切换引脚
		/// </summary>
		/// <param name="aNew"></param>
		/// <param name="aOld"></param>
		/// <param name="aPurpose"></param>
		/// <returns></returns>
		private bool SwitchPin(string aNew, string aOld, PinPurpose aPurpose)
		{
			if (this.Enable)
			{
				if (mParent.PinIsUsedTips(aNew))
				{
					return false;
				}
				mUsePins[aPurpose - PinPurpose.SOFT_IIC_SCL] = aNew;
				SetPins(mUsePins);
				// 清除占用的功能脚
				mParent.ResetPins(aOld);
			}
			else
			{
				mUsePins[aPurpose - PinPurpose.SOFT_IIC_SCL] = aNew;
			}
			return true;
		}

		private string mSCL = string.Empty;
		[DisplayName("时钟引脚"),
		Description("模拟I2C的时钟引脚(SCL)"),
		TypeConverter(typeof(PinsConvertor))]
		public string SCL
		{
			get => mSCL;
			set
			{
				if (value != mSCL)
				{
					if (!SwitchPin(value, mSCL, PinPurpose.SOFT_IIC_SCL))
					{
						return;
					}
					mSCL = value;
				}
			}
		}

		private string mSDA = string.Empty;
		[DisplayName("数据引脚"),
		Description("模拟I2C的数据引脚(SDA)"),
		TypeConverter(typeof(PinsConvertor))]
		public string SDA
		{
			get => mSDA;
			set
			{
				if (value != mSDA)
				{
					if (!SwitchPin(value, mSDA, PinPurpose.SOFT_IIC_SDA))
					{
						return;
					}
					mSDA = value;
				}
			}
		}

		protected override void SetPins(String[] aPins)
		{
			base.SetPins(aPins);
			var purpose = PinPurpose.SOFT_IIC_SCL;
			for (int i = 0; i < 2; i++)
			{
				mParent.SetPinPurpose(aPins[i], purpose, false);
				purpose++;
			}
		}

		/// <summary>
		/// 设置的引脚是否有效
		/// </summary>
		/// <returns></returns>
		public bool PinsValid()
		{
			foreach (var pin in mUsePins)
			{
				if (mParent.GetPin(pin) == null)
				{
					return false;
				}
			}

			return true;
		}

		public SoftIICOptions(STC32GQFP64 aParent) : base(aParent)
		{
			this.Type = IICTypes.Soft;
			mUsePins = new string[] { SCL, SDA };
		}

		/// <summary>
		/// 创建需要的库文件
		/// </summary>
		/// <param name="aPath"></param>
		/// <param name="aPins"></param>
		/// <returns></returns>
		public bool CreateLibFiles(string aPath)
		{
			string file = "STC32G_Soft_I2C.c";
			var pairs = TemplateHelper.CreatePairs();

			pairs["SoftSCL"] = mParent.GetPin(mUsePins[0]) == null ? "P66" : mUsePins[0].Replace(".", "");
			pairs["SoftSDA"] = mParent.GetPin(mUsePins[1]) == null ? "P66" : mUsePins[1].Replace(".", "");

			return mParent.CreateByTemplate(PrjPathTypes.Drivers_STC32_Src, aPath, file, true, pairs);
		}

		public Boolean AppendConfig(string aPath, List<String[]> aLst)
		{
			if (!this.Enable)
			{
				return false;
			}

			Dictionary<string, List<string>> lst = new Dictionary<string, List<string>>();
			foreach (var pin in mUsePins)
			{
				var opt = mParent.GetPinOption(pin);
				if (opt != null)
				{
					opt.ToDictionary(lst);
				}
			}
			if (lst.Count < 2)
			{
				// 未设置引脚
				return false;
			}

			if (!CreateLibFiles(aPath))
			{
				return false;
			}

			string name = "SoftIIC_Config";
			StringBuilder funcSb = new StringBuilder();
			funcSb.Append(TemplateHelper.GetFunctionCommit("模拟I2C模块初始化"));
			funcSb.AppendLine($"PRIVATE void {name}(void)").AppendLine("{");

			funcSb.Append(GPIOOptions.GetGPIOConfigs(lst));
			funcSb.AppendLine("}");
			aLst.Add(new string[] { funcSb.ToString(), $"{name}();" });

			return true;
		}
	}
}
